package com.tinyseed.emcp.api.dashboard.service.impl;

import com.tinyseed.emcp.api.basicdata.repository.EnterpriseRepository;
import com.tinyseed.emcp.api.basicdata.repository.MonitorRepository;
import com.tinyseed.emcp.api.basicdata.repository.OrganizeRepository;
import com.tinyseed.emcp.api.basicdata.repository.WorkshopRepository;
import com.tinyseed.emcp.api.basicdata.service.OrganizeService;
import com.tinyseed.emcp.api.dashboard.entity.BasicInfo;
import com.tinyseed.emcp.api.dashboard.entity.DashboardView;
import com.tinyseed.emcp.api.dashboard.query.TreeQuickQuery;
import com.tinyseed.emcp.api.dashboard.repository.DashboardViewRepository;
import com.tinyseed.emcp.api.dashboard.service.DashboardService;
import com.tinyseed.emcp.api.exception.service.ExceptionInfoService;
import com.tinyseed.emcp.api.productionRule.bean.DistributionOutputDTO;
import com.tinyseed.emcp.api.productionRule.entity.Reduction;
import com.tinyseed.emcp.api.productionRule.service.DistributionService;
import com.tinyseed.emcp.api.productionRule.service.ReductionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @version Revision 1.0.0
 * @版权：SINOSERVICES 版权所有 (c) 2013
 * @author:Leen
 * @email:Howard.Wu@sinoservices.com
 * @see:
 * @创建日期：2019年2月5日
 * @功能说明：
 * @begin
 * @修改记录:
 * @修改后版本 修改人        修改内容
 * @2019年2月5日 Howard            创建
 * @end 控制台
 */
@Slf4j
@Service
public class DashboardServiceImpl implements DashboardService {

    @Autowired
    private OrganizeService organizeService;

    @Autowired
    private OrganizeRepository organizeRepository;

    @Autowired
    private EnterpriseRepository enterpriseRepository;

    @Autowired
    private WorkshopRepository workshopRepository;

    @Autowired
    private MonitorRepository monitorRepository;

    @Autowired
    private ReductionService reductionService;

    @Autowired
    private DistributionService distributionService;

    @Autowired
    private DashboardViewRepository dashboardViewRepository;

    @Autowired
    private ExceptionInfoService exceptionInfoService;


    @Override
    public List<TreeQuickQuery> allMonitorRelationTree() {

        HashMap<Long, TreeQuickQuery> map = new HashMap<>();
        /*递归查找省市区县的list 并组装*/
        List<TreeQuickQuery> tree = new ArrayList<>(organizeRepository.queryOrganizeTree());
        tree.addAll(enterpriseRepository.findEnterpriseTree());
        tree.addAll(workshopRepository.queryWorkshopTree());
        tree.addAll(monitorRepository.queryMonitorTree());
        tree.forEach(item -> {
            map.put(item.getId(), item);
        });
        List<TreeQuickQuery> result = new ArrayList<>();
        for (Map.Entry<Long, TreeQuickQuery> entry : map.entrySet()) {
            TreeQuickQuery node = entry.getValue();
            if (node.getPid() == null) {
                log.info(node.toString());
            }

            if (node == null || node.getPid() == null || node.getPid() == 0L) {
                result.add(node);
            } else {
                /*没有开辟新空间，所以是引用类型传递*/
                if (map.get(node.getPid()) != null) {
                    map.get(node.getPid()).addChild(node);
                }
            }
        }
        return result;
    }

    @Override
    public BasicInfo basicInfo() {

        /*公司数目*/
        Long enterpriseCount = enterpriseRepository.count();
        /*监测点点数*/
        Long monitorCount = monitorRepository.count();
        /*产物点数*/
        Long monitorProduceCount = monitorRepository.countByEquipmentTypeEquals("1");
        /*治污点数*/
        Long monitorCtrCount = monitorRepository.countByEquipmentTypeEquals("2");
        return BasicInfo.builder()
                .enterpriseCount(enterpriseCount)
                .monitorCount(monitorCount)
                .monitorCtrCount(monitorCtrCount)
                .monitorProduceCount(monitorProduceCount)
                .build();

    }

    @Override
    public void getExceptionInfo() {
        //今日异常情况
        Long exceptionCount = exceptionInfoService.exceptionInfoDashboard();
        exceptionInfoService.exceptionInfoForEnterprise();
    }


    @Override
    public void saveTodayDashboardView() {
        DashboardView dashboardView = computeEnterpriseStatue();
        dashboardViewRepository.save(dashboardView);
    }

    @Override
    public void computeEnterpriseRunnerStatue() {

    }


    @Override
    public DashboardView computeEnterpriseStatue() {
        List<HashMap> list = searchLimitAndStopEnterprise();

        HashMap h = list.get(1);
        /*限产*/
        AtomicInteger limitEnterprise = new AtomicInteger();
        /*停产*/
        AtomicInteger stopEnterprise = new AtomicInteger();
        /*停产+限产*/
        AtomicInteger stopAndLimitEnterprise = new AtomicInteger();

        h.forEach((key, value) -> {
            if ((Long) value == 0) {
                /*0是限产*/
                limitEnterprise.getAndIncrement();
            } else if (((Long) value == 1)) {
                stopEnterprise.getAndIncrement();
            } else {
                stopAndLimitEnterprise.getAndIncrement();
            }
        });
        return DashboardView.builder()
                .limitEnterprise(limitEnterprise.intValue())
                .stopAndLimitEnterprise(stopAndLimitEnterprise.intValue())
                .stopEnterprise(stopEnterprise.intValue()).build();

    }

    public void saveDayLimitState() {
        dashboardViewRepository.save(computeEnterpriseStatue());
    }

    public DashboardView getYesterdayLimitState() {
        return dashboardViewRepository.findTopByOrderByIdDesc();
    }


    /*构建monitorMap*/
    private HashMap<Long, DistributionOutputDTO> buildMonitorMap(List<Reduction> reductions) {
        /*查找所有监测点的状态*/
        HashMap<Long, DistributionOutputDTO> monitorDirstrbutions = new HashMap<>();
        reductions.forEach(reduction -> {
            List<DistributionOutputDTO> distributions
                    = distributionService.findAllByProducesetId(reduction.getId());
            Long level = reduction.getLevel();
            Long produceType = reduction.getProduceType();
            Double lessProduce = reduction.getLessProduce();
            distributions.forEach(distributionOutputDTO -> {
                distributionOutputDTO.setLevel(level);
                distributionOutputDTO.setLessProduce(lessProduce);
                distributionOutputDTO.setProduceType(produceType);

                Long monitorId = distributionOutputDTO.getMonitorId();

                /*获取在hashmap中的 规则*/
                DistributionOutputDTO distribution = monitorDirstrbutions.get(monitorId);
                /* 存入所有监测点 */
                /*都是减产，减产优先级大的大于减产小的*/
                /*level 同等级 停产优先级大于限产*/
                /*level越高优先级越大*/
                if (!StringUtils.isEmpty(distribution)) {
                    if (distributionOutputDTO.compareTo(distribution) == 0) {
                        monitorDirstrbutions.put(monitorId, distributionOutputDTO);
                    }
                } else {
                    monitorDirstrbutions.put(monitorId, distributionOutputDTO);
                }

            });
        });
        return monitorDirstrbutions;
    }

    /*根据监测点的规则map，构建enterpriseMap*/
    private List<HashMap> buildEnterpriseMapByMonitorDirstrbutionMap(HashMap<Long, DistributionOutputDTO> monitorDirstrbutions) {
        HashMap<Long, List<DistributionOutputDTO>> enterpriseMap = new HashMap<>();
        HashMap<Long, Long> enterpriseStatus = new HashMap<>();

        /*取出监测点map种的规则*/
        for (Long key : monitorDirstrbutions.keySet()) {
            DistributionOutputDTO distributionOutputDTO = monitorDirstrbutions.get(key);
            /* 如果发现enterprise的key已经存在。则在value数组中添加*/
            if (enterpriseMap.containsKey(key)) {
                enterpriseMap.get(key).add(distributionOutputDTO);
                if (!enterpriseStatus.get(key).equals(distributionOutputDTO.getProduceType())) {
                    enterpriseStatus.put(key, 2L);
                }
            } else {
                /*如果没存在id则直接加入*/
                List<DistributionOutputDTO> tempList = new ArrayList<>();
                tempList.add(distributionOutputDTO);
                enterpriseMap.put(distributionOutputDTO.getEnterpriseId(), tempList);

                /*存入状态hashMap*/
                enterpriseStatus.put(distributionOutputDTO.getEnterpriseId(), distributionOutputDTO.getProduceType());

            }
        }
        List<HashMap> listMap = new ArrayList<>();
        listMap.add(enterpriseMap);
        listMap.add(enterpriseStatus);

        return listMap;
    }

    /*查找限停限产的企业*/
    private List<HashMap> searchLimitAndStopEnterprise() {
        List<Reduction> reductions = reductionService.getActiveList();
        /*查找所有监测点的状态*/
        HashMap<Long, DistributionOutputDTO> monitorDirstrbutions = buildMonitorMap(reductions);
        List<HashMap> listMap = buildEnterpriseMapByMonitorDirstrbutionMap(monitorDirstrbutions);

        return listMap;
    }

}
